using System;
using System.Collections.Generic;
using System.Text;
using System.Data.SqlClient;
using AopLoadBalancer.Server.BusinessLogic;

namespace AopLoadBalancer.Server.DataAccess
{
    internal class AliveNotificationDal
    {
        private readonly DalSession session;

        public AliveNotificationDal(DalSession session)
        {
            this.session = session;
        }

        public AliveNotification GetByUrl(string serviceUrl)
        {
            const string query = "Select * from aliveNotification where serviceUrl=@serviceUrl";
            using (SqlCommand command = session.CreateCommand(query))
            {
                command.Parameters.Add(new SqlParameter("serviceUrl", serviceUrl));

                using (SqlDataReader reader = command.ExecuteReader())
                {
                    if (!reader.Read())
                    {
                        return null;
                        //throw new DataAccessException(string.Format("Entry with id '{0}' not found.", serviceUrl));
                    }
                    else
                    {
                        return ExtractFromReader(reader);
                    }
                }
            }
        }

        public void Add(AliveNotification aliveNotification)
        {
            const string query =
                @"insert into aliveNotification(serviceId,ServiceUrl,LastAliveTick)
                            values(@serviceId,@serviceUrl,@lastAliveTick)";
            using (SqlCommand command = session.CreateCommand(query))
            {
                command.Parameters.Add(new SqlParameter("serviceId", aliveNotification.ServiceId));
                command.Parameters.Add(new SqlParameter("serviceUrl", aliveNotification.ServiceUrl));
                command.Parameters.Add(
                    new SqlParameter("lastAliveTick", GetLastAliveTickParamValue(aliveNotification.LastAliveTick)));

                command.ExecuteNonQuery();
            }
        }

        public void Update(AliveNotification aliveNotification)
        {
            string text = "update alivenotification set serviceId=@serviceId, lastAliveTick=@lastAliveTick where serviceUrl = @serviceUrl";
            using (SqlCommand command = session.CreateCommand(text))
            {
                command.Parameters.Add(new SqlParameter("serviceId", aliveNotification.ServiceId));
                command.Parameters.Add(new SqlParameter("serviceUrl", aliveNotification.ServiceUrl));

                object lastAliveTickParamValue = GetLastAliveTickParamValue(aliveNotification.LastAliveTick);
                command.Parameters.Add(
                    new SqlParameter("lastAliveTick",
                                     lastAliveTickParamValue));

                int rowsAffected = command.ExecuteNonQuery();
                if (rowsAffected != 1)
                {
                    throw new DataAccessException("Invalid number of affected rows. Expected 1, modified " +
                                                  rowsAffected);
                }
            }
        }

        private static object GetLastAliveTickParamValue(DateTime lastAliveTick)
        {
            return lastAliveTick == DateTime.MinValue
                       ? (object) DBNull.Value
                       : lastAliveTick;
        }

        private static AliveNotification ExtractFromReader(SqlDataReader reader)
        {
            string serviceId = Convert.ToString(reader["serviceId"]);
            string serviceUrl = Convert.ToString(reader["serviceUrl"]);
            object lastAliveTickObj = reader["lastAliveTick"];
            DateTime lastAliveTick = lastAliveTickObj == DBNull.Value ? DateTime.MinValue : (DateTime) lastAliveTickObj;

            AliveNotification aliveNotification = new AliveNotification(serviceId, serviceUrl, lastAliveTick);
            return aliveNotification;
        }

        public List<AliveNotification> GetByLastAliveTick(string serviceId,DateTime aliveLastTick)
        {
            const string query = "select * from AliveNotification where LastAliveTick>=@lastAliveTick and serviceId=@serviceID";
            using(SqlCommand command=session.CreateCommand(query))
            {
                command.Parameters.Add(new SqlParameter("lastAliveTick", aliveLastTick));
                command.Parameters.Add(new SqlParameter("serviceId", serviceId));

                List < AliveNotification> ret=new List<AliveNotification>();

                using(SqlDataReader reader=command.ExecuteReader())
                {
                    while(reader.Read())
                    {
                        ret.Add(ExtractFromReader(reader));
                    }
                }
                return ret;
            }
        }
    }
}